// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.vehicles;

import gnu.trove.list.array.TShortArrayList;
import gnu.trove.map.hash.TShortShortHashMap;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.joml.Quaternionf;
import org.joml.Vector3f;
import zombie.Lua.LuaEventManager;
import zombie.characters.IsoGameCharacter;
import zombie.characters.IsoPlayer;
import zombie.core.network.ByteBufferWriter;
import zombie.core.physics.Bullet;
import zombie.core.physics.Transform;
import zombie.core.physics.WorldSimulation;
import zombie.core.raknet.UdpConnection;
import zombie.core.utils.UpdateLimit;
import zombie.debug.DebugLog;
import zombie.inventory.InventoryItem;
import zombie.inventory.types.DrainableComboItem;
import zombie.iso.IsoChunk;
import zombie.iso.IsoGridSquare;
import zombie.iso.IsoObject;
import zombie.iso.IsoWorld;
import zombie.network.GameClient;
import zombie.network.GameServer;
import zombie.network.PacketTypes;
import zombie.network.packets.VehicleAuthorizationPacket;
import zombie.network.packets.vehicle.Physics;
import zombie.scripting.objects.VehicleScript;
import zombie.util.Type;

public final class VehicleManager {
    public static VehicleManager instance;
    private final VehicleIDMap IDToVehicle = VehicleIDMap.instance;
    private final ArrayList<BaseVehicle> vehicles = new ArrayList();
    private boolean idMapDirty = true;
    private final Transform tempTransform = new Transform();
    private final ArrayList<BaseVehicle> sendReliable = new ArrayList();
    private final ArrayList<BaseVehicle> sendUnreliable = new ArrayList();
    private final TShortArrayList vehiclesWaitUpdates = new TShortArrayList(128);
    private final TShortShortHashMap towedVehicleMap = new TShortShortHashMap();
    public static HashMap<Byte, String> vehiclePacketTypes = new HashMap();
    public final UdpConnection[] connected = new UdpConnection[512];
    private final float[] tempFloats = new float[27];
    private final float[] engineSound = new float[2];
    private final VehicleManager.PosUpdateVars posUpdateVars = new VehicleManager.PosUpdateVars();
    private final UpdateLimit vehiclesWaitUpdatesFrequency = new UpdateLimit(1000L);
    private BaseVehicle tempVehicle;
    private final ArrayList<BaseVehicle.ModelInfo> oldModels = new ArrayList();
    private final ArrayList<BaseVehicle.ModelInfo> curModels = new ArrayList();
    private final UpdateLimit sendRequestGetPositionFrequency = new UpdateLimit(500L);
    private final UpdateLimit VehiclePhysicSyncPacketLimit = new UpdateLimit(500L);

    public void registerVehicle(BaseVehicle vehicle) {
        this.IDToVehicle.put(vehicle.VehicleID, vehicle);
        this.idMapDirty = true;
    }

    public void unregisterVehicle(BaseVehicle vehicle) {
        this.IDToVehicle.remove(vehicle.VehicleID);
        this.idMapDirty = true;
    }

    public BaseVehicle getVehicleByID(short id) {
        return this.IDToVehicle.get(id);
    }

    public ArrayList<BaseVehicle> getVehicles() {
        if (this.idMapDirty) {
            this.vehicles.clear();
            this.IDToVehicle.toArrayList(this.vehicles);
            this.idMapDirty = false;
        }

        return this.vehicles;
    }

    public void removeFromWorld(BaseVehicle vehicle) {
        if (vehicle.VehicleID != -1) {
            DebugLog.Vehicle.trace("removeFromWorld vehicle id=%d", vehicle.VehicleID);
            this.unregisterVehicle(vehicle);
            if (GameServer.bServer) {
                for (int _int = 0; _int < GameServer.udpEngine.connections.size(); _int++) {
                    UdpConnection udpConnection = (UdpConnection)GameServer.udpEngine.connections.get(_int);
                    if (vehicle.connectionState[udpConnection.index] != null) {
                        ByteBufferWriter byteBufferWriter = udpConnection.startPacket();
                        PacketTypes.PacketType.Vehicles.doPacket(byteBufferWriter);
                        byteBufferWriter.bb.put((byte)8);
                        byteBufferWriter.bb.putShort(vehicle.VehicleID);
                        PacketTypes.PacketType.Vehicles.send(udpConnection);
                    }
                }
            }

            if (GameClient.bClient) {
                vehicle.serverRemovedFromWorld = false;
                if (vehicle.interpolation != null) {
                    vehicle.interpolation.clear();
                }
            }
        }
    }

    public void serverUpdate() {
        ArrayList arrayList = IsoWorld.instance.CurrentCell.getVehicles();

        for (int int0 = 0; int0 < this.connected.length; int0++) {
            if (this.connected[int0] != null && !GameServer.udpEngine.connections.contains(this.connected[int0])) {
                DebugLog.Vehicle.trace("vehicles: dropped connection %d", int0);

                for (int int1 = 0; int1 < arrayList.size(); int1++) {
                    ((BaseVehicle)arrayList.get(int1)).connectionState[int0] = null;
                }

                this.connected[int0] = null;
            } else {
                for (int int2 = 0; int2 < arrayList.size(); int2++) {
                    if (((BaseVehicle)arrayList.get(int2)).connectionState[int0] != null) {
                        BaseVehicle.ServerVehicleState serverVehicleState = ((BaseVehicle)arrayList.get(int2)).connectionState[int0];
                        serverVehicleState.flags = (short)(serverVehicleState.flags | ((BaseVehicle)arrayList.get(int2)).updateFlags);
                    }
                }
            }
        }

        for (int int3 = 0; int3 < GameServer.udpEngine.connections.size(); int3++) {
            UdpConnection udpConnection = (UdpConnection)GameServer.udpEngine.connections.get(int3);
            this.sendVehicles(udpConnection, PacketTypes.PacketType.VehiclesUnreliable.getId());
            this.connected[udpConnection.index] = udpConnection;
        }

        for (int int4 = 0; int4 < arrayList.size(); int4++) {
            BaseVehicle baseVehicle = (BaseVehicle)arrayList.get(int4);
            if ((baseVehicle.updateFlags & 19440) != 0) {
                for (int int5 = 0; int5 < baseVehicle.getPartCount(); int5++) {
                    VehiclePart vehiclePart = baseVehicle.getPartByIndex(int5);
                    vehiclePart.updateFlags = 0;
                }
            }

            baseVehicle.updateFlags = 0;
        }
    }

    private void sendVehicles(UdpConnection udpConnection, short _short) {
        if (udpConnection.isFullyConnected()) {
            this.sendReliable.clear();
            this.sendUnreliable.clear();
            ArrayList arrayList = IsoWorld.instance.CurrentCell.getVehicles();

            for (int _int = 0; _int < arrayList.size(); _int++) {
                BaseVehicle baseVehicle = (BaseVehicle)arrayList.get(_int);
                if (baseVehicle.VehicleID == -1) {
                    baseVehicle.VehicleID = this.IDToVehicle.allocateID();
                    this.registerVehicle(baseVehicle);
                }

                if (udpConnection.RelevantTo(baseVehicle.x, baseVehicle.y)) {
                    if (baseVehicle.connectionState[udpConnection.index] == null) {
                        baseVehicle.connectionState[udpConnection.index] = new BaseVehicle.ServerVehicleState();
                    }

                    BaseVehicle.ServerVehicleState serverVehicleState = baseVehicle.connectionState[udpConnection.index];
                    if (serverVehicleState.shouldSend(baseVehicle)) {
                        if (!baseVehicle.isReliable && PacketTypes.PacketType.Vehicles.getId() != _short) {
                            this.sendUnreliable.add(baseVehicle);
                        } else {
                            this.sendReliable.add(baseVehicle);
                        }
                    }
                }
            }

            this.sendVehiclesInternal(udpConnection, this.sendReliable, PacketTypes.PacketType.Vehicles);
            this.sendVehiclesInternal(udpConnection, this.sendUnreliable, PacketTypes.PacketType.VehiclesUnreliable);
        }
    }

    private void sendVehiclesInternal(UdpConnection udpConnection, ArrayList<BaseVehicle> arrayList, PacketTypes.PacketType packetType) {
        if (!arrayList.isEmpty()) {
            ByteBufferWriter byteBufferWriter0 = udpConnection.startPacket();
            packetType.doPacket(byteBufferWriter0);

            try {
                ByteBuffer byteBuffer = byteBufferWriter0.bb;
                byteBuffer.put((byte)5);
                byteBuffer.putShort((short)arrayList.size());

                for (int int0 = 0; int0 < arrayList.size(); int0++) {
                    BaseVehicle baseVehicle0 = (BaseVehicle)arrayList.get(int0);
                    BaseVehicle.ServerVehicleState serverVehicleState0 = baseVehicle0.connectionState[udpConnection.index];
                    byteBuffer.putShort(baseVehicle0.VehicleID);
                    byteBuffer.putShort(serverVehicleState0.flags);
                    byteBuffer.putFloat(baseVehicle0.x);
                    byteBuffer.putFloat(baseVehicle0.y);
                    byteBuffer.putFloat(baseVehicle0.jniTransform.origin.y);
                    int int1 = byteBuffer.position();
                    byteBuffer.putShort((short)0);
                    int int2 = byteBuffer.position();
                    boolean _boolean = (serverVehicleState0.flags & 1) != 0;
                    if (_boolean) {
                        serverVehicleState0.flags = (short)(serverVehicleState0.flags & -2);
                        baseVehicle0.netPlayerServerSendAuthorisation(byteBuffer);
                        serverVehicleState0.setAuthorization(baseVehicle0);
                        int int3 = byteBuffer.position();
                        byteBuffer.putShort((short)0);
                        baseVehicle0.save(byteBuffer);
                        int int4 = byteBuffer.position();
                        byteBuffer.position(int3);
                        byteBuffer.putShort((short)(int4 - int3));
                        byteBuffer.position(int4);
                        int int5 = byteBuffer.position();
                        int int6 = byteBuffer.position() - int2;
                        byteBuffer.position(int1);
                        byteBuffer.putShort((short)int6);
                        byteBuffer.position(int5);
                        this.writePositionOrientation(byteBuffer, baseVehicle0);
                        serverVehicleState0.x = baseVehicle0.x;
                        serverVehicleState0.y = baseVehicle0.y;
                        serverVehicleState0.z = baseVehicle0.jniTransform.origin.y;
                        serverVehicleState0.orient.set(baseVehicle0.savedRot);
                    } else {
                        if ((serverVehicleState0.flags & 2) != 0) {
                            this.writePositionOrientation(byteBuffer, baseVehicle0);
                            serverVehicleState0.x = baseVehicle0.x;
                            serverVehicleState0.y = baseVehicle0.y;
                            serverVehicleState0.z = baseVehicle0.jniTransform.origin.y;
                            serverVehicleState0.orient.set(baseVehicle0.savedRot);
                        }

                        if ((serverVehicleState0.flags & 4) != 0) {
                            byteBuffer.put((byte)baseVehicle0.engineState.ordinal());
                            byteBuffer.putInt(baseVehicle0.engineLoudness);
                            byteBuffer.putInt(baseVehicle0.enginePower);
                            byteBuffer.putInt(baseVehicle0.engineQuality);
                        }

                        if ((serverVehicleState0.flags & 4096) != 0) {
                            byteBuffer.put((byte)(baseVehicle0.isHotwired() ? 1 : 0));
                            byteBuffer.put((byte)(baseVehicle0.isHotwiredBroken() ? 1 : 0));
                            byteBuffer.putFloat(baseVehicle0.getRegulatorSpeed());
                            byteBuffer.put((byte)(baseVehicle0.isPreviouslyEntered() ? 1 : 0));
                            byteBuffer.put((byte)(baseVehicle0.isKeysInIgnition() ? 1 : 0));
                            byteBuffer.put((byte)(baseVehicle0.isKeyIsOnDoor() ? 1 : 0));
                            InventoryItem inventoryItem0 = baseVehicle0.getCurrentKey();
                            if (inventoryItem0 == null) {
                                byteBuffer.put((byte)0);
                            } else {
                                byteBuffer.put((byte)1);
                                inventoryItem0.saveWithSize(byteBuffer, false);
                            }

                            byteBuffer.putFloat(baseVehicle0.getRust());
                            byteBuffer.putFloat(baseVehicle0.getBloodIntensity("Front"));
                            byteBuffer.putFloat(baseVehicle0.getBloodIntensity("Rear"));
                            byteBuffer.putFloat(baseVehicle0.getBloodIntensity("Left"));
                            byteBuffer.putFloat(baseVehicle0.getBloodIntensity("Right"));
                            byteBuffer.putFloat(baseVehicle0.getColorHue());
                            byteBuffer.putFloat(baseVehicle0.getColorSaturation());
                            byteBuffer.putFloat(baseVehicle0.getColorValue());
                            byteBuffer.putInt(baseVehicle0.getSkinIndex());
                        }

                        if ((serverVehicleState0.flags & 8) != 0) {
                            byteBuffer.put((byte)(baseVehicle0.getHeadlightsOn() ? 1 : 0));
                            byteBuffer.put((byte)(baseVehicle0.getStoplightsOn() ? 1 : 0));

                            for (int int7 = 0; int7 < baseVehicle0.getLightCount(); int7++) {
                                byteBuffer.put((byte)(baseVehicle0.getLightByIndex(int7).getLight().getActive() ? 1 : 0));
                            }
                        }

                        if ((serverVehicleState0.flags & 1024) != 0) {
                            byteBuffer.put((byte)(baseVehicle0.soundHornOn ? 1 : 0));
                            byteBuffer.put((byte)(baseVehicle0.soundBackMoveOn ? 1 : 0));
                            byteBuffer.put((byte)baseVehicle0.lightbarLightsMode.get());
                            byteBuffer.put((byte)baseVehicle0.lightbarSirenMode.get());
                        }

                        if ((serverVehicleState0.flags & 2048) != 0) {
                            for (int int8 = 0; int8 < baseVehicle0.getPartCount(); int8++) {
                                VehiclePart vehiclePart0 = baseVehicle0.getPartByIndex(int8);
                                if ((vehiclePart0.updateFlags & 2048) != 0) {
                                    byteBuffer.put((byte)int8);
                                    byteBuffer.putInt(vehiclePart0.getCondition());
                                }
                            }

                            byteBuffer.put((byte)-1);
                        }

                        if ((serverVehicleState0.flags & 16) != 0) {
                            for (int int9 = 0; int9 < baseVehicle0.getPartCount(); int9++) {
                                VehiclePart vehiclePart1 = baseVehicle0.getPartByIndex(int9);
                                if ((vehiclePart1.updateFlags & 16) != 0) {
                                    byteBuffer.put((byte)int9);
                                    vehiclePart1.getModData().save(byteBuffer);
                                }
                            }

                            byteBuffer.put((byte)-1);
                        }

                        if ((serverVehicleState0.flags & 32) != 0) {
                            for (int int10 = 0; int10 < baseVehicle0.getPartCount(); int10++) {
                                VehiclePart vehiclePart2 = baseVehicle0.getPartByIndex(int10);
                                if ((vehiclePart2.updateFlags & 32) != 0) {
                                    InventoryItem inventoryItem1 = vehiclePart2.getInventoryItem();
                                    if (inventoryItem1 instanceof DrainableComboItem) {
                                        byteBuffer.put((byte)int10);
                                        byteBuffer.putFloat(((DrainableComboItem)inventoryItem1).getUsedDelta());
                                    }
                                }
                            }

                            byteBuffer.put((byte)-1);
                        }

                        if ((serverVehicleState0.flags & 128) != 0) {
                            for (int int11 = 0; int11 < baseVehicle0.getPartCount(); int11++) {
                                VehiclePart vehiclePart3 = baseVehicle0.getPartByIndex(int11);
                                if ((vehiclePart3.updateFlags & 128) != 0) {
                                    byteBuffer.put((byte)int11);
                                    InventoryItem inventoryItem2 = vehiclePart3.getInventoryItem();
                                    if (inventoryItem2 == null) {
                                        byteBuffer.put((byte)0);
                                    } else {
                                        byteBuffer.put((byte)1);

                                        try {
                                            vehiclePart3.getInventoryItem().saveWithSize(byteBuffer, false);
                                        } catch (Exception exception0) {
                                            exception0.printStackTrace();
                                        }
                                    }
                                }
                            }

                            byteBuffer.put((byte)-1);
                        }

                        if ((serverVehicleState0.flags & 512) != 0) {
                            for (int int12 = 0; int12 < baseVehicle0.getPartCount(); int12++) {
                                VehiclePart vehiclePart4 = baseVehicle0.getPartByIndex(int12);
                                if ((vehiclePart4.updateFlags & 512) != 0) {
                                    byteBuffer.put((byte)int12);
                                    vehiclePart4.getDoor().save(byteBuffer);
                                }
                            }

                            byteBuffer.put((byte)-1);
                        }

                        if ((serverVehicleState0.flags & 256) != 0) {
                            for (int int13 = 0; int13 < baseVehicle0.getPartCount(); int13++) {
                                VehiclePart vehiclePart5 = baseVehicle0.getPartByIndex(int13);
                                if ((vehiclePart5.updateFlags & 256) != 0) {
                                    byteBuffer.put((byte)int13);
                                    vehiclePart5.getWindow().save(byteBuffer);
                                }
                            }

                            byteBuffer.put((byte)-1);
                        }

                        if ((serverVehicleState0.flags & 64) != 0) {
                            byteBuffer.put((byte)baseVehicle0.models.size());

                            for (int int14 = 0; int14 < baseVehicle0.models.size(); int14++) {
                                BaseVehicle.ModelInfo modelInfo = (BaseVehicle.ModelInfo)baseVehicle0.models.get(int14);
                                byteBuffer.put((byte)modelInfo.part.getIndex());
                                byteBuffer.put((byte)modelInfo.part.getScriptPart().models.indexOf(modelInfo.scriptModel));
                            }
                        }

                        int int15 = byteBuffer.position();
                        int int16 = byteBuffer.position() - int2;
                        byteBuffer.position(int1);
                        byteBuffer.putShort((short)int16);
                        byteBuffer.position(int15);
                    }
                }

                packetType.send(udpConnection);
            } catch (Exception exception1) {
                udpConnection.cancelPacket();
                exception1.printStackTrace();
            }

            for (int int17 = 0; int17 < arrayList.size(); int17++) {
                BaseVehicle baseVehicle1 = (BaseVehicle)arrayList.get(int17);
                BaseVehicle.ServerVehicleState serverVehicleState1 = baseVehicle1.connectionState[udpConnection.index];
                if ((serverVehicleState1.flags & 16384) != 0) {
                    VehicleAuthorizationPacket vehicleAuthorizationPacket = new VehicleAuthorizationPacket();
                    vehicleAuthorizationPacket.set(baseVehicle1, udpConnection);
                    ByteBufferWriter byteBufferWriter1 = udpConnection.startPacket();
                    PacketTypes.PacketType.VehicleAuthorization.doPacket(byteBufferWriter1);
                    vehicleAuthorizationPacket.write(byteBufferWriter1);
                    PacketTypes.PacketType.VehicleAuthorization.send(udpConnection);
                }
            }
        }
    }

    public void serverPacket(ByteBuffer bb, UdpConnection connection, short type) {
        byte byte0 = bb.get();
        switch (byte0) {
            case 1:
                short short5 = bb.getShort();
                DebugLog.Vehicle.trace("%s vid=%d", vehiclePacketTypes.get(byte0), short5);
                byte byte2 = bb.get();
                String string = zombie.GameWindow.ReadString(bb);
                BaseVehicle baseVehicle3 = this.IDToVehicle.get(short5);
                if (baseVehicle3 != null) {
                    IsoGameCharacter isoGameCharacter = baseVehicle3.getCharacter(byte2);
                    if (isoGameCharacter != null) {
                        baseVehicle3.setCharacterPosition(isoGameCharacter, byte2, string);
                        this.sendPassengerPosition(baseVehicle3, byte2, string, connection);
                    }
                }
                break;
            case 2:
                short short9 = bb.getShort();
                short short10 = bb.getShort();
                byte byte4 = bb.get();
                DebugLog.Vehicle.trace("Vehicle enter vid=%d pid=%d seat=%d", short9, short10, Integer.valueOf(byte4));
                BaseVehicle baseVehicle6 = this.IDToVehicle.get(short9);
                if (baseVehicle6 == null) {
                    DebugLog.Vehicle.warn("Vehicle vid=%d not found", short9);
                } else {
                    IsoPlayer isoPlayer1 = (IsoPlayer)GameServer.IDToPlayerMap.get(short10);
                    if (isoPlayer1 == null) {
                        DebugLog.Vehicle.warn("Player pid=%d not found", short10);
                    } else {
                        IsoPlayer isoPlayer2 = Type.tryCastTo(baseVehicle6.getCharacter(byte4), IsoPlayer.class);
                        if (isoPlayer2 != null && isoPlayer2 != isoPlayer1) {
                            DebugLog.Vehicle.warn(isoPlayer1.getUsername() + " got in same seat as " + isoPlayer2.getUsername());
                        } else {
                            baseVehicle6.enter(byte4, isoPlayer1);
                            if (byte4 == 0 && baseVehicle6.isNetPlayerAuthorization(BaseVehicle.Authorization.Server)) {
                                baseVehicle6.authorizationServerOnSeat(isoPlayer1, true);
                            }

                            this.sendEnter(baseVehicle6, isoPlayer1, byte4);
                        }
                    }
                }
                break;
            case 3:
                short short1 = bb.getShort();
                short short2 = bb.getShort();
                byte byte1 = bb.get();
                DebugLog.Vehicle.trace("Vehicle exit vid=%d pid=%d seat=%d", short1, short2, Integer.valueOf(byte1));
                BaseVehicle baseVehicle1 = this.IDToVehicle.get(short1);
                if (baseVehicle1 == null) {
                    DebugLog.Vehicle.warn("Vehicle vid=%d not found", short1);
                } else {
                    IsoPlayer isoPlayer0 = (IsoPlayer)GameServer.IDToPlayerMap.get(short2);
                    if (isoPlayer0 == null) {
                        DebugLog.Vehicle.warn("Player pid=%d not found", short2);
                    } else {
                        baseVehicle1.exit(isoPlayer0);
                        if (byte1 == 0) {
                            baseVehicle1.authorizationServerOnSeat(isoPlayer0, false);
                        }

                        this.sendExit(baseVehicle1, isoPlayer0, byte1);
                    }
                }
                break;
            case 4:
                short short11 = bb.getShort();
                short short12 = bb.getShort();
                byte byte5 = bb.get();
                byte byte6 = bb.get();
                DebugLog.Vehicle.trace("Vehicle switch seat vid=%d pid=%d seats=%d=>%d", short11, short12, Integer.valueOf(byte5), Integer.valueOf(byte6));
                BaseVehicle baseVehicle7 = this.IDToVehicle.get(short11);
                if (baseVehicle7 == null) {
                    DebugLog.Vehicle.warn("Vehicle vid=%d not found", short11);
                } else {
                    IsoPlayer isoPlayer3 = (IsoPlayer)GameServer.IDToPlayerMap.get(short12);
                    if (isoPlayer3 == null) {
                        DebugLog.Vehicle.warn("Player pid=%d not found", short12);
                    } else {
                        IsoPlayer isoPlayer4 = Type.tryCastTo(baseVehicle7.getCharacter(byte6), IsoPlayer.class);
                        if (isoPlayer4 != null && isoPlayer4 != isoPlayer3) {
                            DebugLog.Vehicle.warn(isoPlayer3.getUsername() + " switched to same seat as " + isoPlayer4.getUsername());
                        } else {
                            baseVehicle7.switchSeat(isoPlayer3, byte6);
                            if (byte6 == 0 && baseVehicle7.isNetPlayerAuthorization(BaseVehicle.Authorization.Server)) {
                                baseVehicle7.authorizationServerOnSeat(isoPlayer3, true);
                            } else if (byte5 == 0) {
                                baseVehicle7.authorizationServerOnSeat(isoPlayer3, false);
                            }

                            this.sendSwitchSeat(baseVehicle7, isoPlayer3, byte5, byte6);
                        }
                    }
                }
                break;
            case 5:
            case 6:
            case 7:
            case 8:
            case 10:
            case 13:
            case 14:
            default:
                DebugLog.Vehicle.warn("Unknown vehicle packet %d", byte0);
                break;
            case 9:
                Physics physics = new Physics();
                physics.parse(bb, connection);
                physics.process();

                for (int int1 = 0; int1 < GameServer.udpEngine.connections.size(); int1++) {
                    UdpConnection udpConnection0 = (UdpConnection)GameServer.udpEngine.connections.get(int1);
                    if (connection != udpConnection0 && physics.isRelevant(udpConnection0)) {
                        ByteBufferWriter byteBufferWriter0 = udpConnection0.startPacket();
                        PacketTypes.PacketType packetType = (PacketTypes.PacketType)PacketTypes.packetTypes.get(type);
                        packetType.doPacket(byteBufferWriter0);
                        byteBufferWriter0.bb.put((byte)9);
                        physics.write(byteBufferWriter0);
                        packetType.send(udpConnection0);
                    }
                }
                break;
            case 11:
                short short6 = bb.getShort();

                for (int int0 = 0; int0 < short6; int0++) {
                    short short7 = bb.getShort();
                    DebugLog.Vehicle.trace("Vehicle vid=%d full update response ", short7);
                    BaseVehicle baseVehicle4 = this.IDToVehicle.get(short7);
                    if (baseVehicle4 != null) {
                        if (baseVehicle4.connectionState[connection.index] == null) {
                            baseVehicle4.connectionState[connection.index] = new BaseVehicle.ServerVehicleState();
                        }

                        baseVehicle4.connectionState[connection.index].flags = (short)(baseVehicle4.connectionState[connection.index].flags | 1);
                        this.sendVehicles(connection, type);
                    }
                }
                break;
            case 12:
                short short0 = bb.getShort();
                DebugLog.Vehicle.trace("%s vid=%d", vehiclePacketTypes.get(byte0), short0);
                BaseVehicle baseVehicle0 = this.IDToVehicle.get(short0);
                if (baseVehicle0 != null) {
                    baseVehicle0.updateFlags = (short)(baseVehicle0.updateFlags | 2);
                    this.sendVehicles(connection, type);
                }
                break;
            case 15:
                short short3 = bb.getShort();
                short short4 = bb.getShort();
                boolean _boolean = bb.get() == 1;
                DebugLog.Vehicle.trace("%s vid=%d pid=%d %b", vehiclePacketTypes.get(byte0), short3, short4, _boolean);
                BaseVehicle baseVehicle2 = this.IDToVehicle.get(short3);
                if (baseVehicle2 != null) {
                    baseVehicle2.authorizationServerCollide(short4, _boolean);
                }
                break;
            case 16:
                short short8 = bb.getShort();
                DebugLog.Vehicle.trace("%s vid=%d", vehiclePacketTypes.get(byte0), short8);
                byte byte3 = bb.get();
                BaseVehicle baseVehicle5 = this.IDToVehicle.get(short8);
                if (baseVehicle5 != null) {
                    for (int int2 = 0; int2 < GameServer.udpEngine.connections.size(); int2++) {
                        UdpConnection udpConnection1 = (UdpConnection)GameServer.udpEngine.connections.get(int2);
                        if (udpConnection1 != connection) {
                            ByteBufferWriter byteBufferWriter1 = udpConnection1.startPacket();
                            PacketTypes.PacketType.Vehicles.doPacket(byteBufferWriter1);
                            byteBufferWriter1.bb.put((byte)16);
                            byteBufferWriter1.bb.putShort(baseVehicle5.VehicleID);
                            byteBufferWriter1.bb.put(byte3);
                            PacketTypes.PacketType.Vehicles.send(udpConnection1);
                        }
                    }
                }
        }
    }

    public void serverSendInitialWorldState(UdpConnection connection) {
        ByteBufferWriter byteBufferWriter = connection.startPacket();
        PacketTypes.PacketType.Vehicles.doPacket(byteBufferWriter);
        byteBufferWriter.bb.put((byte)19);
        byteBufferWriter.bb.putShort((short)this.towedVehicleMap.size());
        this.towedVehicleMap.forEachEntry((short0, short1) -> {
            byteBufferWriter.putShort(short0);
            byteBufferWriter.putShort(short1);
            return true;
        });
        PacketTypes.PacketType.Vehicles.send(connection);
    }

    private void vehiclePosUpdate(BaseVehicle baseVehicle, float[] float5) {
        int int0 = 0;
        Transform transform = this.posUpdateVars.transform;
        Vector3f vector3f0 = this.posUpdateVars.vector3f;
        Quaternionf quaternionf = this.posUpdateVars.quatf;
        float[] float0 = this.posUpdateVars.wheelSteer;
        float[] float1 = this.posUpdateVars.wheelRotation;
        float[] float2 = this.posUpdateVars.wheelSkidInfo;
        float[] float3 = this.posUpdateVars.wheelSuspensionLength;
        float float4 = float5[int0++] - WorldSimulation.instance.offsetX;
        float float6 = float5[int0++] - WorldSimulation.instance.offsetY;
        float float7 = float5[int0++];
        transform.origin.set(float4, float7, float6);
        float float8 = float5[int0++];
        float float9 = float5[int0++];
        float float10 = float5[int0++];
        float float11 = float5[int0++];
        quaternionf.set(float8, float9, float10, float11);
        quaternionf.normalize();
        transform.setRotation(quaternionf);
        float float12 = float5[int0++];
        float float13 = float5[int0++];
        float float14 = float5[int0++];
        vector3f0.set(float12, float13, float14);
        int int1 = (int)float5[int0++];

        for (int int2 = 0; int2 < int1; int2++) {
            float0[int2] = float5[int0++];
            float1[int2] = float5[int0++];
            float2[int2] = float5[int0++];
            float3[int2] = float5[int0++];
        }

        baseVehicle.jniTransform.set(transform);
        baseVehicle.jniLinearVelocity.set(vector3f0);
        baseVehicle.jniTransform.basis.getScale(vector3f0);
        if ((double)vector3f0.x < 0.99 || (double)vector3f0.y < 0.99 || (double)vector3f0.z < 0.99) {
            baseVehicle.jniTransform.basis.scale(1.0F / vector3f0.x, 1.0F / vector3f0.y, 1.0F / vector3f0.z);
        }

        baseVehicle.jniSpeed = baseVehicle.jniLinearVelocity.length() * 3.6F;
        Vector3f vector3f1 = baseVehicle.getForwardVector(BaseVehicle.allocVector3f());
        if (vector3f1.dot(baseVehicle.jniLinearVelocity) < 0.0F) {
            baseVehicle.jniSpeed *= -1.0F;
        }

        BaseVehicle.releaseVector3f(vector3f1);

        for (int int3 = 0; int3 < 4; int3++) {
            baseVehicle.wheelInfo[int3].steering = float0[int3];
            baseVehicle.wheelInfo[int3].rotation = float1[int3];
            baseVehicle.wheelInfo[int3].skidInfo = float2[int3];
            baseVehicle.wheelInfo[int3].suspensionLength = float3[int3];
        }

        baseVehicle.polyDirty = true;
    }

    public void clientUpdate() {
        if (this.vehiclesWaitUpdatesFrequency.Check()) {
            if (this.vehiclesWaitUpdates.size() > 0) {
                ByteBufferWriter byteBufferWriter = GameClient.connection.startPacket();
                PacketTypes.PacketType.Vehicles.doPacket(byteBufferWriter);
                byteBufferWriter.bb.put((byte)11);
                byteBufferWriter.bb.putShort((short)this.vehiclesWaitUpdates.size());

                for (int int0 = 0; int0 < this.vehiclesWaitUpdates.size(); int0++) {
                    byteBufferWriter.bb.putShort(this.vehiclesWaitUpdates.get(int0));
                }

                PacketTypes.PacketType.Vehicles.send(GameClient.connection);
            }

            this.vehiclesWaitUpdates.clear();
        }

        ArrayList arrayList = this.getVehicles();

        for (int int1 = 0; int1 < arrayList.size(); int1++) {
            BaseVehicle baseVehicle = (BaseVehicle)arrayList.get(int1);
            if (GameClient.bClient) {
                if (baseVehicle.isNetPlayerAuthorization(BaseVehicle.Authorization.Local)
                    || baseVehicle.isNetPlayerAuthorization(BaseVehicle.Authorization.LocalCollide)) {
                    baseVehicle.interpolation.clear();
                    continue;
                }
            } else if (baseVehicle.isKeyboardControlled() || baseVehicle.getJoypad() != -1) {
                baseVehicle.interpolation.clear();
                continue;
            }

            float[] float0 = this.tempFloats;
            if (baseVehicle.interpolation.interpolationDataGet(float0, this.engineSound)) {
                if (!baseVehicle.isNetPlayerAuthorization(BaseVehicle.Authorization.Local)
                    && !baseVehicle.isNetPlayerAuthorization(BaseVehicle.Authorization.LocalCollide)) {
                    Bullet.setOwnVehiclePhysics(baseVehicle.VehicleID, float0);
                    float float1 = float0[0];
                    float float2 = float0[1];
                    float float3 = float0[2];
                    IsoGridSquare isoGridSquare = IsoWorld.instance.CurrentCell.getGridSquare((double)float1, (double)float2, 0.0);
                    this.clientUpdateVehiclePos(baseVehicle, float1, float2, float3, isoGridSquare);
                    baseVehicle.limitPhysicValid.BlockCheck();
                    if (GameClient.bClient) {
                        this.vehiclePosUpdate(baseVehicle, float0);
                    }

                    baseVehicle.engineSpeed = (double)this.engineSound[0];
                    baseVehicle.throttle = this.engineSound[1];
                }
            } else {
                baseVehicle.getController().control_NoControl();
                baseVehicle.throttle = 0.0F;
                baseVehicle.jniSpeed = 0.0F;
            }
        }
    }

    private void clientUpdateVehiclePos(BaseVehicle baseVehicle, float float0, float float1, float var4, IsoGridSquare isoGridSquare) {
        baseVehicle.setX(float0);
        baseVehicle.setY(float1);
        baseVehicle.setZ(0.0F);
        baseVehicle.square = isoGridSquare;
        baseVehicle.setCurrent(isoGridSquare);
        if (isoGridSquare != null) {
            if (baseVehicle.chunk != null && baseVehicle.chunk != isoGridSquare.chunk) {
                baseVehicle.chunk.vehicles.remove(baseVehicle);
            }

            baseVehicle.chunk = baseVehicle.square.chunk;
            if (!baseVehicle.chunk.vehicles.contains(baseVehicle)) {
                baseVehicle.chunk.vehicles.add(baseVehicle);
                IsoChunk.addFromCheckedVehicles(baseVehicle);
            }

            if (!baseVehicle.addedToWorld) {
                baseVehicle.addToWorld();
            }
        } else {
            baseVehicle.removeFromWorld();
            baseVehicle.removeFromSquare();
        }

        baseVehicle.polyDirty = true;
    }

    private void clientReceiveUpdateFull(ByteBuffer byteBuffer, short short2, float float1, float float0, float float2) throws IOException {
        BaseVehicle.Authorization authorization = BaseVehicle.Authorization.valueOf(byteBuffer.get());
        short short0 = byteBuffer.getShort();
        short short1 = byteBuffer.getShort();
        IsoGridSquare isoGridSquare = IsoWorld.instance.CurrentCell.getGridSquare((double)float1, (double)float0, 0.0);
        if (this.IDToVehicle.containsKey(short2)) {
            BaseVehicle baseVehicle0 = this.IDToVehicle.get(short2);
            DebugLog.Vehicle.noise("ERROR: got full update for KNOWN vehicle id=%d", short2);
            byteBuffer.get();
            byteBuffer.get();
            this.tempVehicle.parts.clear();
            this.tempVehicle.load(byteBuffer, 195);
            if (baseVehicle0.physics != null && (baseVehicle0.getDriver() == null || !baseVehicle0.getDriver().isLocal())) {
                this.tempTransform.setRotation(this.tempVehicle.savedRot);
                this.tempTransform.origin.set(float1 - WorldSimulation.instance.offsetX, float2, float0 - WorldSimulation.instance.offsetY);
                baseVehicle0.setWorldTransform(this.tempTransform);
            }

            baseVehicle0.netPlayerFromServerUpdate(authorization, short0);
            this.clientUpdateVehiclePos(baseVehicle0, float1, float0, float2, isoGridSquare);
        } else {
            boolean _boolean = byteBuffer.get() != 0;
            byte _byte = byteBuffer.get();
            if (!_boolean || _byte != IsoObject.getFactoryVehicle().getClassID()) {
                DebugLog.Vehicle.error("clientReceiveUpdateFull: packet broken");
            }

            BaseVehicle baseVehicle1 = new BaseVehicle(IsoWorld.instance.CurrentCell);
            baseVehicle1.VehicleID = short2;
            baseVehicle1.square = isoGridSquare;
            baseVehicle1.setCurrent(isoGridSquare);
            baseVehicle1.load(byteBuffer, 195);
            if (isoGridSquare != null) {
                baseVehicle1.chunk = baseVehicle1.square.chunk;
                baseVehicle1.chunk.vehicles.add(baseVehicle1);
                baseVehicle1.addToWorld();
            }

            IsoChunk.addFromCheckedVehicles(baseVehicle1);
            baseVehicle1.netPlayerFromServerUpdate(authorization, short0);
            this.registerVehicle(baseVehicle1);

            for (int _int = 0; _int < IsoPlayer.numPlayers; _int++) {
                IsoPlayer isoPlayer = IsoPlayer.players[_int];
                if (isoPlayer != null && !isoPlayer.isDead() && isoPlayer.getVehicle() == null) {
                    IsoWorld.instance.CurrentCell.putInVehicle(isoPlayer);
                }
            }

            DebugLog.Vehicle.trace("added vehicle id=%d %s", baseVehicle1.VehicleID, isoGridSquare == null ? " (delayed)" : "");
        }
    }

    private void clientReceiveUpdate(ByteBuffer byteBuffer) throws IOException {
        short short0 = byteBuffer.getShort();
        DebugLog.Vehicle.trace("%s vid=%d", vehiclePacketTypes.get((byte)5), short0);
        short short1 = byteBuffer.getShort();
        float float0 = byteBuffer.getFloat();
        float float1 = byteBuffer.getFloat();
        float float2 = byteBuffer.getFloat();
        short short2 = byteBuffer.getShort();
        VehicleCache.vehicleUpdate(short0, float0, float1, 0.0F);
        IsoGridSquare isoGridSquare = IsoWorld.instance.CurrentCell.getGridSquare((double)float0, (double)float1, 0.0);
        BaseVehicle baseVehicle = this.IDToVehicle.get(short0);
        if (baseVehicle == null && isoGridSquare == null) {
            if (byteBuffer.limit() > byteBuffer.position() + short2) {
                byteBuffer.position(byteBuffer.position() + short2);
            }
        } else if (baseVehicle != null && isoGridSquare == null) {
            boolean boolean0 = true;

            for (int int0 = 0; int0 < IsoPlayer.numPlayers; int0++) {
                IsoPlayer isoPlayer = IsoPlayer.players[int0];
                if (isoPlayer != null && isoPlayer.getVehicle() == baseVehicle) {
                    boolean0 = false;
                    isoPlayer.setPosition(float0, float1, 0.0F);
                    this.sendRequestGetPosition(short0, PacketTypes.PacketType.VehiclesUnreliable);
                }
            }

            if (boolean0) {
                baseVehicle.removeFromWorld();
                baseVehicle.removeFromSquare();
            }

            if (byteBuffer.limit() > byteBuffer.position() + short2) {
                byteBuffer.position(byteBuffer.position() + short2);
            }
        } else if ((short1 & 1) != 0) {
            DebugLog.Vehicle.trace("Vehicle vid=%d full update received", short0);
            this.clientReceiveUpdateFull(byteBuffer, short0, float0, float1, float2);
            if (baseVehicle == null) {
                baseVehicle = this.IDToVehicle.get(short0);
            }

            if (!baseVehicle.isKeyboardControlled() && baseVehicle.getJoypad() == -1) {
                byteBuffer.getLong();
                int int1 = 0;
                float[] float3 = this.tempFloats;
                float3[int1++] = float0;
                float3[int1++] = float1;
                float3[int1++] = float2;

                while (int1 < 10) {
                    float3[int1++] = byteBuffer.getFloat();
                }

                float float4 = byteBuffer.getFloat();
                float float5 = byteBuffer.getFloat();
                short short3 = byteBuffer.getShort();
                float3[int1++] = (float)short3;

                for (int int2 = 0; int2 < short3; int2++) {
                    float3[int1++] = byteBuffer.getFloat();
                    float3[int1++] = byteBuffer.getFloat();
                    float3[int1++] = byteBuffer.getFloat();
                    float3[int1++] = byteBuffer.getFloat();
                }

                Bullet.setOwnVehiclePhysics(short0, float3);
            } else if (byteBuffer.limit() > byteBuffer.position() + 102) {
                byteBuffer.position(byteBuffer.position() + 102);
            }

            int int3 = this.vehiclesWaitUpdates.indexOf(short0);
            if (int3 >= 0) {
                this.vehiclesWaitUpdates.removeAt(int3);
            }
        } else if (baseVehicle == null && isoGridSquare != null) {
            this.sendRequestGetFull(short0, PacketTypes.PacketType.Vehicles);
            if (byteBuffer.limit() > byteBuffer.position() + short2) {
                byteBuffer.position(byteBuffer.position() + short2);
            }
        } else {
            if ((short1 & 2) != 0) {
                if (!baseVehicle.isKeyboardControlled() && baseVehicle.getJoypad() == -1) {
                    baseVehicle.interpolation
                        .interpolationDataAdd(byteBuffer, byteBuffer.getLong(), float0, float1, float2, zombie.GameTime.getServerTimeMills());
                } else if (byteBuffer.limit() > byteBuffer.position() + 102) {
                    byteBuffer.position(byteBuffer.position() + 102);
                }
            }

            if ((short1 & 4) != 0) {
                DebugLog.Vehicle.trace("received update Engine id=%d", short0);
                byte byte0 = byteBuffer.get();
                if (byte0 >= 0 && byte0 < BaseVehicle.engineStateTypes.Values.length) {
                    switch (BaseVehicle.engineStateTypes.Values[byte0]) {
                        case Idle:
                            baseVehicle.engineDoIdle();
                        case Starting:
                        default:
                            break;
                        case RetryingStarting:
                            baseVehicle.engineDoRetryingStarting();
                            break;
                        case StartingSuccess:
                            baseVehicle.engineDoStartingSuccess();
                            break;
                        case StartingFailed:
                            baseVehicle.engineDoStartingFailed();
                            break;
                        case StartingFailedNoPower:
                            baseVehicle.engineDoStartingFailedNoPower();
                            break;
                        case Running:
                            baseVehicle.engineDoRunning();
                            break;
                        case Stalling:
                            baseVehicle.engineDoStalling();
                            break;
                        case ShutingDown:
                            baseVehicle.engineDoShuttingDown();
                    }

                    baseVehicle.engineLoudness = byteBuffer.getInt();
                    baseVehicle.enginePower = byteBuffer.getInt();
                    baseVehicle.engineQuality = byteBuffer.getInt();
                } else {
                    DebugLog.Vehicle.error("VehicleManager.clientReceiveUpdate get invalid data");
                }
            }

            if ((short1 & 4096) != 0) {
                DebugLog.Vehicle.trace("received car properties update id=%d", short0);
                baseVehicle.setHotwired(byteBuffer.get() == 1);
                baseVehicle.setHotwiredBroken(byteBuffer.get() == 1);
                baseVehicle.setRegulatorSpeed(byteBuffer.getFloat());
                baseVehicle.setPreviouslyEntered(byteBuffer.get() == 1);
                boolean boolean1 = byteBuffer.get() == 1;
                boolean boolean2 = byteBuffer.get() == 1;
                InventoryItem inventoryItem0 = null;
                if (byteBuffer.get() == 1) {
                    try {
                        inventoryItem0 = InventoryItem.loadItem(byteBuffer, 195);
                    } catch (Exception exception0) {
                        exception0.printStackTrace();
                    }
                }

                baseVehicle.syncKeyInIgnition(boolean1, boolean2, inventoryItem0);
                baseVehicle.setRust(byteBuffer.getFloat());
                baseVehicle.setBloodIntensity("Front", byteBuffer.getFloat());
                baseVehicle.setBloodIntensity("Rear", byteBuffer.getFloat());
                baseVehicle.setBloodIntensity("Left", byteBuffer.getFloat());
                baseVehicle.setBloodIntensity("Right", byteBuffer.getFloat());
                baseVehicle.setColorHSV(byteBuffer.getFloat(), byteBuffer.getFloat(), byteBuffer.getFloat());
                baseVehicle.setSkinIndex(byteBuffer.getInt());
                baseVehicle.updateSkin();
            }

            if ((short1 & 8) != 0) {
                DebugLog.Vehicle.trace("received update Lights id=%d", short0);
                baseVehicle.setHeadlightsOn(byteBuffer.get() == 1);
                baseVehicle.setStoplightsOn(byteBuffer.get() == 1);

                for (int int4 = 0; int4 < baseVehicle.getLightCount(); int4++) {
                    boolean boolean3 = byteBuffer.get() == 1;
                    baseVehicle.getLightByIndex(int4).getLight().setActive(boolean3);
                }
            }

            if ((short1 & 1024) != 0) {
                DebugLog.Vehicle.trace("received update Sounds id=%d", short0);
                boolean boolean4 = byteBuffer.get() == 1;
                boolean boolean5 = byteBuffer.get() == 1;
                byte byte1 = byteBuffer.get();
                byte byte2 = byteBuffer.get();
                if (boolean4 != baseVehicle.soundHornOn) {
                    if (boolean4) {
                        baseVehicle.onHornStart();
                    } else {
                        baseVehicle.onHornStop();
                    }
                }

                if (boolean5 != baseVehicle.soundBackMoveOn) {
                    if (boolean5) {
                        baseVehicle.onBackMoveSignalStart();
                    } else {
                        baseVehicle.onBackMoveSignalStop();
                    }
                }

                if (baseVehicle.lightbarLightsMode.get() != byte1) {
                    baseVehicle.setLightbarLightsMode(byte1);
                }

                if (baseVehicle.lightbarSirenMode.get() != byte2) {
                    baseVehicle.setLightbarSirenMode(byte2);
                }
            }

            if ((short1 & 2048) != 0) {
                for (byte byte3 = byteBuffer.get(); byte3 != -1; byte3 = byteBuffer.get()) {
                    VehiclePart vehiclePart0 = baseVehicle.getPartByIndex(byte3);
                    DebugLog.Vehicle.trace("received update PartCondition id=%d part=%s", short0, vehiclePart0.getId());
                    vehiclePart0.updateFlags = (short)(vehiclePart0.updateFlags | 2048);
                    vehiclePart0.setCondition(byteBuffer.getInt());
                }

                baseVehicle.doDamageOverlay();
            }

            if ((short1 & 16) != 0) {
                for (byte byte4 = byteBuffer.get(); byte4 != -1; byte4 = byteBuffer.get()) {
                    VehiclePart vehiclePart1 = baseVehicle.getPartByIndex(byte4);
                    DebugLog.Vehicle.trace("received update PartModData id=%d part=%s", short0, vehiclePart1.getId());
                    vehiclePart1.getModData().load(byteBuffer, 195);
                    if (vehiclePart1.isContainer()) {
                        vehiclePart1.setContainerContentAmount(vehiclePart1.getContainerContentAmount());
                    }
                }
            }

            if ((short1 & 32) != 0) {
                for (byte byte5 = byteBuffer.get(); byte5 != -1; byte5 = byteBuffer.get()) {
                    float float6 = byteBuffer.getFloat();
                    VehiclePart vehiclePart2 = baseVehicle.getPartByIndex(byte5);
                    DebugLog.Vehicle.trace("received update PartUsedDelta id=%d part=%s", short0, vehiclePart2.getId());
                    InventoryItem inventoryItem1 = vehiclePart2.getInventoryItem();
                    if (inventoryItem1 instanceof DrainableComboItem) {
                        ((DrainableComboItem)inventoryItem1).setUsedDelta(float6);
                    }
                }
            }

            if ((short1 & 128) != 0) {
                for (byte byte6 = byteBuffer.get(); byte6 != -1; byte6 = byteBuffer.get()) {
                    VehiclePart vehiclePart3 = baseVehicle.getPartByIndex(byte6);
                    DebugLog.Vehicle.trace("received update PartItem id=%d part=%s", short0, vehiclePart3.getId());
                    vehiclePart3.updateFlags = (short)(vehiclePart3.updateFlags | 128);
                    boolean boolean6 = byteBuffer.get() != 0;
                    if (boolean6) {
                        InventoryItem inventoryItem2;
                        try {
                            inventoryItem2 = InventoryItem.loadItem(byteBuffer, 195);
                        } catch (Exception exception1) {
                            exception1.printStackTrace();
                            return;
                        }

                        if (inventoryItem2 != null) {
                            vehiclePart3.setInventoryItem(inventoryItem2);
                        }
                    } else {
                        vehiclePart3.setInventoryItem(null);
                    }

                    int int5 = vehiclePart3.getWheelIndex();
                    if (int5 != -1) {
                        baseVehicle.setTireRemoved(int5, !boolean6);
                    }

                    if (vehiclePart3.isContainer()) {
                        LuaEventManager.triggerEvent("OnContainerUpdate");
                    }
                }
            }

            if ((short1 & 512) != 0) {
                for (byte byte7 = byteBuffer.get(); byte7 != -1; byte7 = byteBuffer.get()) {
                    VehiclePart vehiclePart4 = baseVehicle.getPartByIndex(byte7);
                    DebugLog.Vehicle.trace("received update PartDoor id=%d part=%s", short0, vehiclePart4.getId());
                    vehiclePart4.getDoor().load(byteBuffer, 195);
                }

                LuaEventManager.triggerEvent("OnContainerUpdate");
                baseVehicle.doDamageOverlay();
            }

            if ((short1 & 256) != 0) {
                for (byte byte8 = byteBuffer.get(); byte8 != -1; byte8 = byteBuffer.get()) {
                    VehiclePart vehiclePart5 = baseVehicle.getPartByIndex(byte8);
                    DebugLog.Vehicle.trace("received update PartWindow id=%d part=%s", short0, vehiclePart5.getId());
                    vehiclePart5.getWindow().load(byteBuffer, 195);
                }

                baseVehicle.doDamageOverlay();
            }

            if ((short1 & 64) != 0) {
                this.oldModels.clear();
                this.oldModels.addAll(baseVehicle.models);
                this.curModels.clear();
                byte byte9 = byteBuffer.get();

                for (int int6 = 0; int6 < byte9; int6++) {
                    byte byte10 = byteBuffer.get();
                    byte byte11 = byteBuffer.get();
                    VehiclePart vehiclePart6 = baseVehicle.getPartByIndex(byte10);
                    VehicleScript.Model model = (VehicleScript.Model)vehiclePart6.getScriptPart().models.get(byte11);
                    BaseVehicle.ModelInfo modelInfo0 = baseVehicle.setModelVisible(vehiclePart6, model, true);
                    this.curModels.add(modelInfo0);
                }

                for (int int7 = 0; int7 < this.oldModels.size(); int7++) {
                    BaseVehicle.ModelInfo modelInfo1 = (BaseVehicle.ModelInfo)this.oldModels.get(int7);
                    if (!this.curModels.contains(modelInfo1)) {
                        baseVehicle.setModelVisible(modelInfo1.part, modelInfo1.scriptModel, false);
                    }
                }

                baseVehicle.doDamageOverlay();
            }

            boolean boolean7 = false;

            for (int int8 = 0; int8 < baseVehicle.getPartCount(); int8++) {
                VehiclePart vehiclePart7 = baseVehicle.getPartByIndex(int8);
                if (vehiclePart7.updateFlags != 0) {
                    if ((vehiclePart7.updateFlags & 2048) != 0 && (vehiclePart7.updateFlags & 128) == 0) {
                        vehiclePart7.doInventoryItemStats(vehiclePart7.getInventoryItem(), vehiclePart7.getMechanicSkillInstaller());
                        boolean7 = true;
                    }

                    vehiclePart7.updateFlags = 0;
                }
            }

            if (boolean7) {
                baseVehicle.updatePartStats();
                baseVehicle.updateBulletStats();
            }
        }
    }

    public void clientPacket(ByteBuffer bb) {
        byte byte0 = bb.get();
        switch (byte0) {
            case 1:
                short short8 = bb.getShort();
                DebugLog.Vehicle.trace("%s vid=%d", vehiclePacketTypes.get(byte0), short8);
                byte byte3 = bb.get();
                String string2 = zombie.GameWindow.ReadString(bb);
                BaseVehicle baseVehicle7 = this.IDToVehicle.get(short8);
                if (baseVehicle7 != null) {
                    IsoGameCharacter isoGameCharacter = baseVehicle7.getCharacter(byte3);
                    if (isoGameCharacter != null) {
                        baseVehicle7.setCharacterPosition(isoGameCharacter, byte3, string2);
                    }
                }
                break;
            case 2:
                short short15 = bb.getShort();
                short short16 = bb.getShort();
                byte byte6 = bb.get();
                DebugLog.Vehicle.trace("Vehicle enter vid=%d pid=%d seat=%d", short15, short16, Integer.valueOf(byte6));
                BaseVehicle baseVehicle10 = this.IDToVehicle.get(short15);
                if (baseVehicle10 == null) {
                    DebugLog.Vehicle.warn("Vehicle vid=%d not found", short15);
                } else {
                    IsoPlayer isoPlayer3 = (IsoPlayer)GameClient.IDToPlayerMap.get(short16);
                    if (isoPlayer3 == null) {
                        DebugLog.Vehicle.warn("Player pid=%d not found", short16);
                    } else {
                        IsoPlayer isoPlayer4 = Type.tryCastTo(baseVehicle10.getCharacter(byte6), IsoPlayer.class);
                        if (isoPlayer4 != null && isoPlayer4 != isoPlayer3) {
                            DebugLog.Vehicle.warn(isoPlayer3.getUsername() + " got in same seat as " + isoPlayer4.getUsername());
                        } else {
                            baseVehicle10.enterRSync(byte6, isoPlayer3, baseVehicle10);
                        }
                    }
                }
                break;
            case 3:
                short short1 = bb.getShort();
                short short2 = bb.getShort();
                byte byte1 = bb.get();
                DebugLog.Vehicle.trace("Vehicle exit vid=%d pid=%d seat=%d", short1, short2, Integer.valueOf(byte1));
                BaseVehicle baseVehicle1 = this.IDToVehicle.get(short1);
                if (baseVehicle1 == null) {
                    DebugLog.Vehicle.warn("Vehicle vid=%d not found", short1);
                } else {
                    IsoPlayer isoPlayer0 = (IsoPlayer)GameClient.IDToPlayerMap.get(short2);
                    if (isoPlayer0 == null) {
                        DebugLog.Vehicle.warn("Player pid=%d not found", short2);
                    } else {
                        baseVehicle1.exitRSync(isoPlayer0);
                    }
                }
                break;
            case 4:
                short short13 = bb.getShort();
                short short14 = bb.getShort();
                byte byte4 = bb.get();
                byte byte5 = bb.get();
                DebugLog.Vehicle.trace("Vehicle switch seat vid=%d pid=%d seats=%d=>%d", short13, short14, Integer.valueOf(byte4), Integer.valueOf(byte5));
                BaseVehicle baseVehicle9 = this.IDToVehicle.get(short13);
                if (baseVehicle9 == null) {
                    DebugLog.Vehicle.warn("Vehicle vid=%d not found", short13);
                } else {
                    IsoPlayer isoPlayer1 = (IsoPlayer)GameClient.IDToPlayerMap.get(short14);
                    if (isoPlayer1 == null) {
                        DebugLog.Vehicle.warn("Player pid=%d not found", short14);
                    } else {
                        IsoPlayer isoPlayer2 = Type.tryCastTo(baseVehicle9.getCharacter(byte5), IsoPlayer.class);
                        if (isoPlayer2 != null && isoPlayer2 != isoPlayer1) {
                            DebugLog.Vehicle.warn(isoPlayer1.getUsername() + " switched to same seat as " + isoPlayer2.getUsername());
                        } else {
                            baseVehicle9.switchSeat(isoPlayer1, byte5);
                        }
                    }
                }
                break;
            case 5:
                if (this.tempVehicle == null || this.tempVehicle.getCell() != IsoWorld.instance.CurrentCell) {
                    this.tempVehicle = new BaseVehicle(IsoWorld.instance.CurrentCell);
                }

                short short17 = bb.getShort();

                for (int int1 = 0; int1 < short17; int1++) {
                    try {
                        this.clientReceiveUpdate(bb);
                    } catch (Exception exception) {
                        exception.printStackTrace();
                        return;
                    }
                }
                break;
            case 6:
            case 7:
            case 10:
            case 11:
            case 12:
            case 14:
            case 15:
            default:
                DebugLog.Vehicle.warn("Unknown vehicle packet %d", byte0);
                break;
            case 8:
                short short9 = bb.getShort();
                DebugLog.Vehicle.trace("%s vid=%d", vehiclePacketTypes.get(byte0), short9);
                if (this.IDToVehicle.containsKey(short9)) {
                    BaseVehicle baseVehicle8 = this.IDToVehicle.get(short9);
                    baseVehicle8.serverRemovedFromWorld = true;

                    try {
                        baseVehicle8.removeFromWorld();
                        baseVehicle8.removeFromSquare();
                    } finally {
                        if (this.IDToVehicle.containsKey(short9)) {
                            this.unregisterVehicle(baseVehicle8);
                        }
                    }
                }

                VehicleCache.remove(short9);
                break;
            case 9:
                Physics physics = new Physics();
                physics.parse(bb, GameClient.connection);
                physics.process();
                break;
            case 13:
                short short0 = bb.getShort();
                DebugLog.Vehicle.trace("%s vid=%d", vehiclePacketTypes.get(byte0), short0);
                Vector3f vector3f0 = new Vector3f();
                Vector3f vector3f1 = new Vector3f();
                vector3f0.x = bb.getFloat();
                vector3f0.y = bb.getFloat();
                vector3f0.z = bb.getFloat();
                vector3f1.x = bb.getFloat();
                vector3f1.y = bb.getFloat();
                vector3f1.z = bb.getFloat();
                BaseVehicle baseVehicle0 = this.IDToVehicle.get(short0);
                if (baseVehicle0 != null) {
                    Bullet.applyCentralForceToVehicle(baseVehicle0.VehicleID, vector3f0.x, vector3f0.y, vector3f0.z);
                    Vector3f vector3f2 = vector3f1.cross(vector3f0);
                    Bullet.applyTorqueToVehicle(baseVehicle0.VehicleID, vector3f2.x, vector3f2.y, vector3f2.z);
                }
                break;
            case 16:
                short short7 = bb.getShort();
                DebugLog.Vehicle.trace("%s vid=%d", vehiclePacketTypes.get(byte0), short7);
                byte byte2 = bb.get();
                BaseVehicle baseVehicle6 = this.IDToVehicle.get(short7);
                if (baseVehicle6 != null) {
                    zombie.SoundManager.instance.PlayWorldSound("VehicleCrash", baseVehicle6.square, 1.0F, 20.0F, 1.0F, true);
                }
                break;
            case 17:
                short short3 = bb.getShort();
                short short4 = bb.getShort();
                String string0 = zombie.GameWindow.ReadString(bb);
                String string1 = zombie.GameWindow.ReadString(bb);
                DebugLog.Vehicle.trace("Vehicle attach A=%d/%s B=%d/%s", short3, string0, short4, string1);
                this.towedVehicleMap.put(short3, short4);
                BaseVehicle baseVehicle2 = this.IDToVehicle.get(short3);
                BaseVehicle baseVehicle3 = this.IDToVehicle.get(short4);
                if (baseVehicle2 != null && baseVehicle3 != null) {
                    baseVehicle2.addPointConstraint(null, baseVehicle3, string0, string1);
                }
                break;
            case 18:
                short short5 = bb.getShort();
                short short6 = bb.getShort();
                DebugLog.Vehicle.trace("Vehicle detach A=%d B=%d", short5, short6);
                if (this.towedVehicleMap.containsKey(short5)) {
                    this.towedVehicleMap.remove(short5);
                }

                if (this.towedVehicleMap.containsKey(short6)) {
                    this.towedVehicleMap.remove(short6);
                }

                BaseVehicle baseVehicle4 = this.IDToVehicle.get(short5);
                BaseVehicle baseVehicle5 = this.IDToVehicle.get(short6);
                if (baseVehicle4 != null) {
                    baseVehicle4.breakConstraint(true, true);
                }

                if (baseVehicle5 != null) {
                    baseVehicle5.breakConstraint(true, true);
                }
                break;
            case 19:
                short short10 = bb.getShort();

                for (int int0 = 0; int0 < short10; int0++) {
                    short short11 = bb.getShort();
                    short short12 = bb.getShort();
                    this.towedVehicleMap.put(short11, short12);
                }
        }
    }

    public void sendCollide(BaseVehicle vehicle, IsoGameCharacter chr, boolean isCollide) {
        short _short = chr == null ? -1 : ((IsoPlayer)chr).OnlineID;
        ByteBufferWriter byteBufferWriter = GameClient.connection.startPacket();
        PacketTypes.PacketType.Vehicles.doPacket(byteBufferWriter);
        byteBufferWriter.bb.put((byte)15);
        byteBufferWriter.bb.putShort(vehicle.VehicleID);
        byteBufferWriter.bb.putShort(_short);
        byteBufferWriter.bb.put((byte)(isCollide ? 1 : 0));
        PacketTypes.PacketType.Vehicles.send(GameClient.connection);
        DebugLog.Vehicle.trace("vid=%d pid=%d collide=%b", vehicle.VehicleID, _short, isCollide);
    }

    public static void sendSound(BaseVehicle vehicle, byte id) {
        ByteBufferWriter byteBufferWriter = GameClient.connection.startPacket();
        PacketTypes.PacketType.Vehicles.doPacket(byteBufferWriter);
        byteBufferWriter.bb.put((byte)16);
        byteBufferWriter.bb.putShort(vehicle.VehicleID);
        byteBufferWriter.bb.put(id);
        PacketTypes.PacketType.Vehicles.send(GameClient.connection);
    }

    public static void sendSoundFromServer(BaseVehicle vehicle, byte soundId) {
        for (int _int = 0; _int < GameServer.udpEngine.connections.size(); _int++) {
            UdpConnection udpConnection = (UdpConnection)GameServer.udpEngine.connections.get(_int);
            ByteBufferWriter byteBufferWriter = udpConnection.startPacket();
            PacketTypes.PacketType.Vehicles.doPacket(byteBufferWriter);
            byteBufferWriter.bb.put((byte)16);
            byteBufferWriter.bb.putShort(vehicle.VehicleID);
            byteBufferWriter.bb.put(soundId);
            PacketTypes.PacketType.Vehicles.send(udpConnection);
        }
    }

    public void sendPassengerPosition(BaseVehicle vehicle, int seat, String positionId) {
        ByteBufferWriter byteBufferWriter = GameClient.connection.startPacket();
        PacketTypes.PacketType.Vehicles.doPacket(byteBufferWriter);
        byteBufferWriter.bb.put((byte)1);
        byteBufferWriter.bb.putShort(vehicle.VehicleID);
        byteBufferWriter.bb.put((byte)seat);
        byteBufferWriter.putUTF(positionId);
        PacketTypes.PacketType.Vehicles.send(GameClient.connection);
    }

    public void sendPassengerPosition(BaseVehicle vehicle, int seat, String positionId, UdpConnection ignore) {
        for (int _int = 0; _int < GameServer.udpEngine.connections.size(); _int++) {
            UdpConnection udpConnection = (UdpConnection)GameServer.udpEngine.connections.get(_int);
            if (udpConnection != ignore) {
                ByteBufferWriter byteBufferWriter = udpConnection.startPacket();
                PacketTypes.PacketType.Vehicles.doPacket(byteBufferWriter);
                byteBufferWriter.bb.put((byte)1);
                byteBufferWriter.bb.putShort(vehicle.VehicleID);
                byteBufferWriter.bb.put((byte)seat);
                byteBufferWriter.putUTF(positionId);
                PacketTypes.PacketType.Vehicles.send(udpConnection);
            }
        }
    }

    public void sendRequestGetFull(short VehicleID, PacketTypes.PacketType packetType) {
        if (!this.vehiclesWaitUpdates.contains(VehicleID)) {
            ByteBufferWriter byteBufferWriter = GameClient.connection.startPacket();
            PacketTypes.PacketType.Vehicles.doPacket(byteBufferWriter);
            byteBufferWriter.bb.put((byte)11);
            byteBufferWriter.bb.putShort((short)1);
            byteBufferWriter.bb.putShort(VehicleID);
            PacketTypes.PacketType.Vehicles.send(GameClient.connection);
            this.vehiclesWaitUpdates.add(VehicleID);
        }
    }

    public void sendRequestGetFull(List<VehicleCache> _vehicles) {
        if (_vehicles != null && !_vehicles.isEmpty()) {
            ByteBufferWriter byteBufferWriter = GameClient.connection.startPacket();
            PacketTypes.PacketType.Vehicles.doPacket(byteBufferWriter);
            byteBufferWriter.bb.put((byte)11);
            byteBufferWriter.bb.putShort((short)_vehicles.size());

            for (int _int = 0; _int < _vehicles.size(); _int++) {
                byteBufferWriter.bb.putShort(((VehicleCache)_vehicles.get(_int)).id);
                this.vehiclesWaitUpdates.add(((VehicleCache)_vehicles.get(_int)).id);
            }

            PacketTypes.PacketType.Vehicles.send(GameClient.connection);
        }
    }

    public void sendRequestGetPosition(short VehicleID, PacketTypes.PacketType packetType) {
        if (this.sendRequestGetPositionFrequency.Check()) {
            ByteBufferWriter byteBufferWriter = GameClient.connection.startPacket();
            packetType.doPacket(byteBufferWriter);
            byteBufferWriter.bb.put((byte)12);
            byteBufferWriter.bb.putShort(VehicleID);
            packetType.send(GameClient.connection);
            this.vehiclesWaitUpdates.add(VehicleID);
        }
    }

    public void sendAddImpulse(BaseVehicle baseVehicle, Vector3f vector3f0, Vector3f vector3f1) {
        UdpConnection udpConnection0 = null;

        for (int int0 = 0; int0 < GameServer.udpEngine.connections.size() && udpConnection0 == null; int0++) {
            UdpConnection udpConnection1 = (UdpConnection)GameServer.udpEngine.connections.get(int0);

            for (int int1 = 0; int1 < udpConnection1.players.length; int1++) {
                IsoPlayer isoPlayer = udpConnection1.players[int1];
                if (isoPlayer != null && isoPlayer.getVehicle() != null && isoPlayer.getVehicle().VehicleID == baseVehicle.VehicleID) {
                    udpConnection0 = udpConnection1;
                    break;
                }
            }
        }

        if (udpConnection0 != null) {
            ByteBufferWriter byteBufferWriter = udpConnection0.startPacket();
            PacketTypes.PacketType.Vehicles.doPacket(byteBufferWriter);
            byteBufferWriter.bb.put((byte)13);
            byteBufferWriter.bb.putShort(baseVehicle.VehicleID);
            byteBufferWriter.bb.putFloat(vector3f0.x);
            byteBufferWriter.bb.putFloat(vector3f0.y);
            byteBufferWriter.bb.putFloat(vector3f0.z);
            byteBufferWriter.bb.putFloat(vector3f1.x);
            byteBufferWriter.bb.putFloat(vector3f1.y);
            byteBufferWriter.bb.putFloat(vector3f1.z);
            PacketTypes.PacketType.Vehicles.send(udpConnection0);
        }
    }

    public void sendSwitchSeat(UdpConnection connection, BaseVehicle vehicle, IsoGameCharacter character, int seatFrom, int seatTo) {
        ByteBufferWriter byteBufferWriter = connection.startPacket();
        PacketTypes.PacketType.Vehicles.doPacket(byteBufferWriter);
        byteBufferWriter.bb.put((byte)4);
        byteBufferWriter.bb.putShort(vehicle.getId());
        byteBufferWriter.bb.putShort(character.getOnlineID());
        byteBufferWriter.bb.put((byte)seatFrom);
        byteBufferWriter.bb.put((byte)seatTo);
        PacketTypes.PacketType.Vehicles.send(connection);
    }

    public void sendSwitchSeat(BaseVehicle vehicle, IsoGameCharacter character, int seatFrom, int seatTo) {
        for (UdpConnection udpConnection : GameServer.udpEngine.connections) {
            this.sendSwitchSeat(udpConnection, vehicle, character, seatFrom, seatTo);
        }
    }

    public void sendEnter(UdpConnection connection, BaseVehicle vehicle, IsoGameCharacter character, int seatTo) {
        ByteBufferWriter byteBufferWriter = connection.startPacket();
        PacketTypes.PacketType.Vehicles.doPacket(byteBufferWriter);
        byteBufferWriter.bb.put((byte)2);
        byteBufferWriter.bb.putShort(vehicle.getId());
        byteBufferWriter.bb.putShort(character.getOnlineID());
        byteBufferWriter.bb.put((byte)seatTo);
        PacketTypes.PacketType.Vehicles.send(connection);
    }

    public void sendEnter(BaseVehicle vehicle, IsoGameCharacter character, int seatTo) {
        for (UdpConnection udpConnection : GameServer.udpEngine.connections) {
            this.sendEnter(udpConnection, vehicle, character, seatTo);
        }
    }

    public void sendExit(UdpConnection connection, BaseVehicle vehicle, IsoGameCharacter character, int seatFrom) {
        ByteBufferWriter byteBufferWriter = connection.startPacket();
        PacketTypes.PacketType.Vehicles.doPacket(byteBufferWriter);
        byteBufferWriter.bb.put((byte)3);
        byteBufferWriter.bb.putShort(vehicle.getId());
        byteBufferWriter.bb.putShort(character.getOnlineID());
        byteBufferWriter.bb.put((byte)seatFrom);
        PacketTypes.PacketType.Vehicles.send(connection);
    }

    public void sendExit(BaseVehicle vehicle, IsoGameCharacter character, int seatFrom) {
        for (UdpConnection udpConnection : GameServer.udpEngine.connections) {
            this.sendExit(udpConnection, vehicle, character, (byte)seatFrom);
        }
    }

    public void sendPhysic(BaseVehicle vehicle) {
        ByteBufferWriter byteBufferWriter = GameClient.connection.startPacket();
        PacketTypes.PacketType packetType = vehicle.isReliable ? PacketTypes.PacketType.Vehicles : PacketTypes.PacketType.VehiclesUnreliable;
        packetType.doPacket(byteBufferWriter);
        byteBufferWriter.bb.put((byte)9);
        Physics physics = new Physics();
        if (physics.set(vehicle)) {
            physics.write(byteBufferWriter);
            packetType.send(GameClient.connection);
        } else {
            GameClient.connection.cancelPacket();
        }
    }

    public void sendTowing(UdpConnection connection, BaseVehicle vehicleA, BaseVehicle vehicleB, String attachmentA, String attachmentB) {
        DebugLog.Vehicle.trace("vidA=%d vidB=%d", vehicleA.VehicleID, vehicleB.VehicleID);
        ByteBufferWriter byteBufferWriter = connection.startPacket();
        PacketTypes.PacketType.Vehicles.doPacket(byteBufferWriter);
        byteBufferWriter.bb.put((byte)17);
        byteBufferWriter.bb.putShort(vehicleA.VehicleID);
        byteBufferWriter.bb.putShort(vehicleB.VehicleID);
        zombie.GameWindow.WriteString(byteBufferWriter.bb, attachmentA);
        zombie.GameWindow.WriteString(byteBufferWriter.bb, attachmentB);
        PacketTypes.PacketType.Vehicles.send(connection);
    }

    public void sendTowing(BaseVehicle vehicleA, BaseVehicle vehicleB, String attachmentA, String attachmentB) {
        if (!this.towedVehicleMap.containsKey(vehicleA.VehicleID)) {
            this.towedVehicleMap.put(vehicleA.VehicleID, vehicleB.VehicleID);

            for (int _int = 0; _int < GameServer.udpEngine.connections.size(); _int++) {
                UdpConnection udpConnection = (UdpConnection)GameServer.udpEngine.connections.get(_int);
                this.sendTowing(udpConnection, vehicleA, vehicleB, attachmentA, attachmentB);
            }
        }
    }

    public void sendDetachTowing(UdpConnection connection, BaseVehicle vehicleA, BaseVehicle vehicleB) {
        ByteBufferWriter byteBufferWriter = connection.startPacket();
        PacketTypes.PacketType.Vehicles.doPacket(byteBufferWriter);
        byteBufferWriter.bb.put((byte)18);
        byteBufferWriter.bb.putShort(vehicleA == null ? -1 : vehicleA.VehicleID);
        byteBufferWriter.bb.putShort(vehicleB == null ? -1 : vehicleB.VehicleID);
        PacketTypes.PacketType.Vehicles.send(connection);
    }

    public void sendDetachTowing(BaseVehicle vehicleTowing, BaseVehicle vehicleTowedBy) {
        if (vehicleTowing != null && this.towedVehicleMap.containsKey(vehicleTowing.VehicleID)) {
            this.towedVehicleMap.remove(vehicleTowing.VehicleID);
        }

        if (vehicleTowedBy != null && this.towedVehicleMap.containsKey(vehicleTowedBy.VehicleID)) {
            this.towedVehicleMap.remove(vehicleTowedBy.VehicleID);
        }

        for (int _int = 0; _int < GameServer.udpEngine.connections.size(); _int++) {
            UdpConnection udpConnection = (UdpConnection)GameServer.udpEngine.connections.get(_int);
            this.sendDetachTowing(udpConnection, vehicleTowing, vehicleTowedBy);
        }
    }

    public short getTowedVehicleID(short towingID) {
        return this.towedVehicleMap.containsKey(towingID) ? this.towedVehicleMap.get(towingID) : -1;
    }

    private void writePositionOrientation(ByteBuffer byteBuffer, BaseVehicle baseVehicle) {
        byteBuffer.putLong(WorldSimulation.instance.time);
        Quaternionf quaternionf = baseVehicle.savedRot;
        Transform transform = baseVehicle.getWorldTransform(this.tempTransform);
        transform.getRotation(quaternionf);
        byteBuffer.putFloat(quaternionf.x);
        byteBuffer.putFloat(quaternionf.y);
        byteBuffer.putFloat(quaternionf.z);
        byteBuffer.putFloat(quaternionf.w);
        byteBuffer.putFloat(baseVehicle.jniLinearVelocity.x);
        byteBuffer.putFloat(baseVehicle.jniLinearVelocity.y);
        byteBuffer.putFloat(baseVehicle.jniLinearVelocity.z);
        byteBuffer.putFloat((float)baseVehicle.engineSpeed);
        byteBuffer.putFloat(baseVehicle.throttle);
        byteBuffer.putShort((short)baseVehicle.wheelInfo.length);

        for (int _int = 0; _int < baseVehicle.wheelInfo.length; _int++) {
            byteBuffer.putFloat(baseVehicle.wheelInfo[_int].steering);
            byteBuffer.putFloat(baseVehicle.wheelInfo[_int].rotation);
            byteBuffer.putFloat(baseVehicle.wheelInfo[_int].skidInfo);
            byteBuffer.putFloat(baseVehicle.wheelInfo[_int].suspensionLength);
        }
    }

    static {
        vehiclePacketTypes.put((byte)1, "PassengerPosition");
        vehiclePacketTypes.put((byte)2, "Enter");
        vehiclePacketTypes.put((byte)3, "Exit");
        vehiclePacketTypes.put((byte)4, "SwitchSeat");
        vehiclePacketTypes.put((byte)5, "Update");
        vehiclePacketTypes.put((byte)8, "Remove");
        vehiclePacketTypes.put((byte)9, "Physic");
        vehiclePacketTypes.put((byte)10, "Config");
        vehiclePacketTypes.put((byte)11, "RequestGetFull");
        vehiclePacketTypes.put((byte)12, "RequestGetPosition");
        vehiclePacketTypes.put((byte)13, "AddImpulse");
        vehiclePacketTypes.put((byte)15, "Collide");
        vehiclePacketTypes.put((byte)16, "Sound");
        vehiclePacketTypes.put((byte)17, "TowingCar");
        vehiclePacketTypes.put((byte)18, "DetachTowingCar");
        vehiclePacketTypes.put((byte)19, "InitialWorldState");
    }

    public static final class PosUpdateVars {
        final Transform transform = new Transform();
        final Vector3f vector3f = new Vector3f();
        final Quaternionf quatf = new Quaternionf();
        final float[] wheelSteer = new float[4];
        final float[] wheelRotation = new float[4];
        final float[] wheelSkidInfo = new float[4];
        final float[] wheelSuspensionLength = new float[4];
    }

    public static final class VehiclePacket {
        public static final byte PassengerPosition = 1;
        public static final byte Enter = 2;
        public static final byte Exit = 3;
        public static final byte SwitchSeat = 4;
        public static final byte Update = 5;
        public static final byte Remove = 8;
        public static final byte Physic = 9;
        public static final byte Config = 10;
        public static final byte RequestGetFull = 11;
        public static final byte RequestGetPosition = 12;
        public static final byte AddImpulse = 13;
        public static final byte Collide = 15;
        public static final byte Sound = 16;
        public static final byte TowingCar = 17;
        public static final byte DetachTowingCar = 18;
        public static final byte InitialWorldState = 19;
        public static final byte Sound_Crash = 1;
    }
}
